﻿using MD5Hash;
using MediatR;
using Microsoft.IdentityModel.Tokens;
using SmartApplication.Api.Applient.Command;
using SmartApplication.Api.Dto;
using SmartApplication.Api.Ext;
using SmartApplication.ApiCode;
using SmartApplication.Domain.Entity;
using SmartApplication.Infrastructure.Instrument;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace SmartApplication.Api.Applient.CommandHandler
{
    public class LoginAccountHandler : IRequestHandler<LoginAccountCommand, ApiResult<LoginDto>>
    {
        public LoginAccountHandler(IBaseRepository<AccountModel> accountRepository,IBaseRepository<RoleModel> roleRepository,IConfiguration configuration)
        {
            AccountRepository = accountRepository;
            RoleRepository = roleRepository;
            Configuration = configuration;
        }

        public IBaseRepository<AccountModel> AccountRepository { get; }
        public IBaseRepository<RoleModel> RoleRepository { get; }
        public IConfiguration Configuration { get; }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ApiResult<LoginDto>> Handle(LoginAccountCommand request, CancellationToken cancellationToken)
        {
            var res=new ApiResult<LoginDto>();

            var acc =  AccountRepository.GetAll().Where(x=>x.AccountName==request.AccountName).FirstOrDefault();
            
            if (acc==null)
            {
                res.Code = EnumCode.Fail;
                res.Message = "用户名不存在";
                return res;
            }
            var lpwd = request.Password.ToMd5();
            if(acc.Password==request.Password)
            {
                res.Code = EnumCode.Fail;
                res.Message = "密码错误";
                return res;
            }
            var role = await RoleRepository.GetValueAsync(acc.RoleId);

            var login = new LoginDto()
            {
                Id = acc.Id,
                RoleId = role.Id,
                AccountName = acc.AccountName,
                RealName = acc.RealName,
                RoleName = role.RoleName,
                Token=CreateTokenString(acc.Id,acc.AccountName)
            };

            res.Code = EnumCode.Success;
            res.Message = "恭喜你,登录成功";
            res.Data = login;
            return res;
        }


        /// <summary>
        /// 生成 JWT Token（令牌）
        /// </summary>
        /// <returns></returns>
        private string CreateTokenString(long Id,string accountname)
        {
            var key = Configuration.GetSection("KeyToken");
            var ketvalue = key["KeyValues"]?? "sdjhfgdhjsjhdfvbjjkdhsdjhfgdhjsjhdfvbjjkdh";
            //私钥
            var secretByte = Encoding.UTF8.GetBytes(ketvalue);
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            var Claims = new List<Claim>
            {
                new Claim("accountName",accountname),
                new Claim("accountId",Id.ToString())
            };
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: key["IsUser"]??"Shanghai",
                audience: key["Audience"] ?? "Shanghai",
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials,
                claims: Claims
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
